/*
 * Copyright (c) 2015. For Intelligent Group.
 */

package com.intelligent.ispc.utils;

import com.intelligent.ispc.external.rcall.dto.RuleResultDto;
import com.intelligent.ispc.external.rcall.common.JudgeRuleType;

/**
 * Created by cherry on 2016/3/31.
 */
public class ControlRuleConfigUtil {

    private int countNum = 0;
    private int countNumSideTop = 0;
    private int countNumSideBottomn = 0;
    private double[] analysData;

    public RuleResultDto setRuleR1(int iPoints, int iSigmaNum, double avgValue, double stdevValue) {
        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else{
            double upperLimit = avgValue + (iSigmaNum * stdevValue);
            double lowerLimit = avgValue - (iSigmaNum * stdevValue);

            ruleResultDto.setRuleName(JudgeRuleType.R1.getCode());

            if (analysData.length < iPoints) {
                return ruleResultDto;
            }

            countNum = 0;

            for (int i = 0; i < analysData.length; i++) {
                if (analysData[i] > upperLimit || analysData[i] < lowerLimit) {
                    countNum++;
                }
            }
            if (countNum >= iPoints) {
                ruleResultDto.setOverRule(true);
                ruleResultDto.setPos(countNum);
            }
            return ruleResultDto;
        }
    }

    public RuleResultDto setRuleR2(int iPoint, double avgValue) {
        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else {
            ruleResultDto.setRuleName(JudgeRuleType.R2.getCode());

            if (analysData.length < iPoint) {
                return ruleResultDto;
            }

            countNum = 0;
            countNumSideTop = 0;
            countNumSideBottomn = 0;

            for (int i = 0; i < analysData.length; i++) {
                if (analysData[i] > avgValue) {
                    countNumSideTop++;
                    if (countNumSideBottomn >= iPoint || countNumSideTop >= iPoint) {
                        break;
                    }
                    countNumSideBottomn = 0;
                } else if (analysData[i] < avgValue) {
                    countNumSideBottomn++;
                    if (countNumSideTop >= iPoint || countNumSideBottomn >= iPoint) {
                        break;
                    }
                    countNumSideTop = 0;
                }
                else {
                    countNumSideTop = 0;
                    countNumSideBottomn = 0;
                    countNum = 0;
                }
            }
            if (countNumSideTop >= iPoint || countNumSideBottomn >= iPoint) {
                ruleResultDto.setOverRule(true);
//                ruleResultDto.setPos(countNum);
            }
            return ruleResultDto;
        }
    }

    public RuleResultDto setRuleR3(int iPoint) {
        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else {
            ruleResultDto.setRuleName(JudgeRuleType.R3.getCode());

            if (analysData.length < iPoint) {
                return ruleResultDto;
            }

            countNumSideBottomn = 1;
            countNumSideTop = 1;

            for (int i = 1; i < analysData.length; i++) {
                if (analysData[i] > analysData[i-1]) {

                    countNumSideTop++;
                    if (countNumSideBottomn >= iPoint || countNumSideTop >= iPoint) {
                        break;
                    }
                    countNumSideBottomn = 1;

                } else if (analysData[i] < analysData[i-1]) {
                    countNumSideBottomn++;
                    if (countNumSideTop >= iPoint || countNumSideBottomn >= iPoint) {
                        break;
                    }
                    countNumSideTop = 1;
                }
                else {
                    countNumSideBottomn = 1;
                    countNumSideTop = 1;
                }
            }
            if (countNumSideTop >= iPoint || countNumSideBottomn >= iPoint) {
                ruleResultDto.setOverRule(true);
//                ruleResultDto.setPos(countNum);
            }
            return ruleResultDto;
        }
    }

    public RuleResultDto setRuleR4(int iPoint) {
        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else {
            ruleResultDto.setRuleName(JudgeRuleType.R4.getCode());

            if (analysData.length < iPoint) {
                return ruleResultDto;
            }

            countNumSideTop = 1;
            countNumSideBottomn = 1;
            countNum = 0;

            for (int i = 1; i < analysData.length; i++) {
                if (analysData[i-1] < analysData[i]) {
                    countNumSideTop ++;
                    countNumSideBottomn = 1;
                    if (countNumSideTop > 2) {
                        countNumSideTop = 1;
                        if ((countNum+1) >= iPoint) {
                            break;
                        }
                        countNum = 0;
                    }
                    else {
                        countNum ++;
                    }
                }
                else if (analysData[i-1] > analysData[i]) {
                    countNumSideBottomn ++;
                    countNumSideTop = 1;
                    if (countNumSideBottomn > 2) {
                        countNumSideBottomn = 1;
                        if ((countNum+1) >= iPoint) {
                            break;
                        }
                        countNum = 0;
                    }
                    else {
                        countNum ++;
                    }
                }
                else {
                    countNumSideTop = 1;
                    countNumSideBottomn = 1;
                    countNum = 0;
                }

                if (countNum+1 >= iPoint) {
                    break;
                }
            }

            if ((countNum+1) >= iPoint) {
                ruleResultDto.setOverRule(true);
            }
            return ruleResultDto;
        }
    }

    public RuleResultDto setRuleR5And6(int iPoint, int iSomePoint, double avgValue, double stdevValue, int iSigmaNum, String rName) {

        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else {

            ruleResultDto.setRuleName(rName);
            if (analysData.length < iPoint) {
                return ruleResultDto;
            }
            double upperLimit = avgValue + (iSigmaNum * stdevValue);
            double lowerLimit = avgValue - (iSigmaNum * stdevValue);

            countNumSideTop = 0;
            countNumSideBottomn = 0;

            for (int i = 0; i <= analysData.length-iPoint; i++) {
                for (int j=0; j<iPoint; j++) {
                    if (analysData[i+j] > upperLimit) {
                        countNumSideTop ++;
                    }

                    if (analysData[i+j] < lowerLimit) {
                        countNumSideBottomn ++;
                    }
                }

                if ((countNumSideTop >= iSomePoint) || (countNumSideBottomn >= iSomePoint)) {
                    ruleResultDto.setOverRule(true);
                    break;
                }

                countNumSideTop = 0;
                countNumSideBottomn = 0;
            }

            return ruleResultDto;
        }
    }

    public RuleResultDto setRuleR7And8(int iPoint, double avgValue, double stdevValue, int iSigmaNum, String rName) {

        RuleResultDto ruleResultDto = new RuleResultDto();

        if (analysData.length == 0) {
            return null;
        } else {
            ruleResultDto.setRuleName(rName);

            if (analysData.length < iPoint) {
                return ruleResultDto;
            }

            double upperLimit = avgValue + (iSigmaNum * stdevValue);
            double lowerLimit = avgValue - (iSigmaNum * stdevValue);
            countNum = 0;

            if (rName.equals(JudgeRuleType.R7.getCode())) {
                for (int i = 0; i < analysData.length; i++) {
                    if (analysData[i] > lowerLimit && analysData[i] < upperLimit) {
                        countNum ++;
                        if (countNum >= iPoint) {
                            break;
                        }
                    }
                    else {
                        countNum = 0;
                    }
                }

                if (countNum >= iPoint) {
                    ruleResultDto.setOverRule(true);
                }
            }

            if (rName.equals(JudgeRuleType.R8.getCode())) {
                for (int i = 0; i < analysData.length; i++) {
                    if (analysData[i] > upperLimit || analysData[i] < lowerLimit) {
                        countNum ++;
                        if (countNum >= iPoint) {
                            break;
                        }
                    }
                    else {
                        countNum = 0;
                    }
                }

                if (countNum >= iPoint) {
                    ruleResultDto.setOverRule(true);
                }
            }
            return ruleResultDto;
        }
    }

    public double[] getAnalysData() {
        return analysData;
    }

    public void setAnalysData(double[] analysData) {
        this.analysData = analysData;
    }
}


